home *** CD-ROM | disk | FTP | other *** search
- /* +-------------------------------------------------------------------+ */
- /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
- /* | | */
- /* | Permission to use, copy, modify, and to distribute this software | */
- /* | and its documentation for any purpose is hereby granted without | */
- /* | fee, provided that the above copyright notice appear in all | */
- /* | copies and that both that copyright notice and this permission | */
- /* | notice appear in supporting documentation. There is no | */
- /* | representations about the suitability of this software for | */
- /* | any purpose. this software is provided "as is" without express | */
- /* | or implied warranty. | */
- /* | | */
- /* +-------------------------------------------------------------------+ */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/cursorfont.h>
- #include <X11/Xaw/Label.h>
- #include <ctype.h>
-
- #include "bitmaps/background.xbm"
-
- #ifndef XtNcursor
- #define XtNcursor "cursor"
- #endif
-
- #include "xpaint.h"
-
- Widget GetToplevel(Widget w)
- {
- Widget p = w;
-
- while (w != None) {
- p = w;
- w = XtParent(w);
- }
- return p;
- }
-
- Widget GetShell(Widget w)
- {
- while (!XtIsShell(w))
- w = XtParent(w);
- return w;
- }
-
- void SetIBeamCursor(Widget w)
- {
- XtVaSetValues(w, XtVaTypedArg,
- XtNcursor, XtRString, "xterm", sizeof(Cursor), NULL);
- }
-
- void SetCrossHairCursor(Widget w)
- {
- XtVaSetValues(w, XtVaTypedArg,
- XtNcursor, XtRString, "crosshair", sizeof(Cursor), NULL);
- }
- void SetPencilCursor(Widget w)
- {
- XtVaSetValues(w, XtVaTypedArg,
- XtNcursor, XtRString, "pencil", sizeof(Cursor), NULL);
- }
-
- /*
- ** Some useful XRectangle computation code.
- */
- XRectangle *RectUnion(XRectangle *a, XRectangle *b)
- {
- static XRectangle out;
- int sx, ex, sy, ey;
-
- sx = MIN(a->x, b->x);
- sy = MIN(a->y, b->y);
- ex = MAX(a->x + a->width, b->x + b->width);
- ey = MAX(a->y + a->height, b->y + b->height);
-
- XYtoRECT(sx, sy, ex, ey, &out);
-
- return &out;
- }
-
- XRectangle *RectIntersect(XRectangle *a, XRectangle *b)
- {
- static XRectangle out;
- int w, h;
-
- if (a == NULL || b == NULL)
- return NULL;
-
- out.x = MAX(a->x, b->x);
- out.y = MAX(a->y, b->y);
- w = MIN(a->x + a->width, b->x + b->width) - out.x;
- h = MIN(a->y + a->height, b->y + b->height) - out.y;
-
- if (w <= 0 || h <= 0)
- return NULL;
-
- out.width = w;
- out.height = h;
-
- return &out;
- }
-
- /*
- **
- */
- void GetPixmapWHD(Display *dpy, Drawable d, int *wth, int *hth, int *dth)
- {
- Window root;
- int x, y;
- unsigned int width, height, bw, depth;
-
- XGetGeometry(dpy, d, &root, &x, &y, &width, &height, &bw, &depth);
-
- if (wth != NULL) *wth = width;
- if (hth != NULL) *hth = height;
- if (dth != NULL) *dth = depth;
- }
-
- /*
- ** Two useful functions to "cache" both a tiled background
- ** and a Xor gc
- */
- typedef struct bgList_s {
- int depth;
- Pixmap pixmap;
- struct bgList_s *next;
- } BackgroundList;
-
- static BackgroundList *bgList = NULL;
-
- Pixmap GetBackgroundPixmap(Widget w)
- {
- Widget p, n;
- Display *dpy = XtDisplay(w);
- int depth;
- Pixmap pix;
- Pixel fg, bg;
- BackgroundList *cur;
- Widget tw;
-
- for (n = XtParent(p=w); !XtIsShell(n); n = XtParent(p=n));
-
- XtVaGetValues(p, XtNdepth, &depth, NULL);
-
- for (cur = bgList; bgList != NULL; bgList = bgList->next)
- if (cur->depth == depth)
- return cur->pixmap;
-
- tw = XtVaCreateWidget("junkWidget", labelWidgetClass, w,
- XtNwidth, 1,
- XtNheight, 1,
- NULL);
- XtVaGetValues(tw, XtNforeground, &fg,
- XtNbackground, &bg,
- NULL);
-
- XtDestroyWidget(tw);
-
- pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
- (char *)background_bits,
- background_width, background_height,
- bg,fg, depth);
-
- cur = XtNew(BackgroundList);
- cur->next = bgList;
- bgList = cur;
- cur->depth = depth;
- cur->pixmap = pix;
- return pix;
- }
-
- typedef struct gcList_s {
- Widget widget;
- int depth;
- GC gc;
- struct gcList_s *next;
- } GCXList;
-
- static GCXList *gcList = NULL;
-
- GC GetGCX(Widget w)
- {
- Widget n = GetShell(w);
- int depth;
- GCXList *cur;
- XGCValues values;
-
- XtVaGetValues(n, XtNdepth, &depth, NULL);
-
- for (cur = gcList; gcList != NULL; gcList = gcList->next)
- if (cur->depth == depth)
- return cur->gc;
-
- values.function = GXxor;
- values.foreground = 1;
-
- cur = XtNew(GCXList);
- cur->next = gcList;
- gcList = cur;
- cur->depth = depth;
- cur->gc = XtGetGC(n, GCFunction|GCForeground, &values);
- return cur->gc;
- }
-
- /*
- ** Argv parsing routines
- */
-
- static char *nextArg(char *str, char **start)
- {
- char *cp;
- int flg;
-
- while (isspace(*str))
- str++;
- if (start != NULL)
- *start = str;
- if (*str == '\0')
- return NULL;
- if (*str == '\'' || *str == '"') {
- char delim = *str;
- if (start != NULL)
- (*start)++;
- cp = ++str;
- while (*str != '\0' && *str != delim) {
- if (*str == '\\') {
- if (*++str == '\0')
- continue;
- }
- *cp++ = *str++;
- }
- *cp = '\0';
- } else {
- while (!isspace(*str) && *str != '\0')
- str++;
- }
-
- flg = (*str != '\0');
- *str = '\0';
- return str + (flg ? 1 : 0);
- }
-
- void StrToArgv(char *str, int *argc, char **argv)
- {
- int t;
- char *cp;
-
- if (argc == NULL)
- argc = &t;
-
- *argc = 0;
- for (cp = str; cp != NULL; (*argc)++)
- cp = nextArg(cp, argv == NULL ? NULL : &argv[*argc]);
-
- if (argv != NULL)
- argv[--(*argc)] = NULL;
- }
-
- /*
- ** Create a XImage
- */
- XImage *NewXImage(Display *dpy, Visual *visual, int depth, int width, int height)
- {
- XImage *xim;
- int pad;
-
- if (depth > 16)
- pad = 32;
- else if (depth > 8)
- pad = 16;
- else
- pad = 8;
-
- xim = XCreateImage(dpy, visual, depth, ZPixmap, 0, NULL, width, height, pad, 0);
-
- if (xim == NULL)
- return NULL;
-
- xim->data = (char*)XtMalloc(xim->bytes_per_line * height);
-
- if (xim->data == NULL) {
- XDestroyImage(xim);
- xim = NULL;
- }
-
- return xim;
- }
-